﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;
using RPGX.Data;
using System.Threading;
using RPGX.Server.Game;
using System.IO;

namespace RPGX.Server.Debugging
{
    public class DatabaseTraceListener : TraceListener
    {
        #region Public Methods

        public DatabaseTraceListener()
        {
            this.ClearLog();
        }

        public override void Write(string message)
        {
            this.WriteLine(message);
        }

        public override void WriteLine(string message)
        {
            if (message == null) // allow empty strings
                return;

            this.LogToDatabase(message, null);
        }

        public override void WriteLine(object o)
        {
            if (o == null)
                return;

            if (o is Exception)
            {
                this.LogToDatabase(String.Empty, o as Exception);
            }
            else
            {
                this.WriteLine(o.ToString());
            }
        }

        public override void Write(object o)
        {
            this.WriteLine(o);
        }

        #endregion

        #region Private Methods

        private void LogToDatabase(string message, Exception ex)
        {
            try
            {
                RPGXServerEntities context = new RPGXServerEntities();

                RPGX.Data.Trace t = new Data.Trace();

                t.DateCreated = DateTime.Now;
                t.Message = message;
                t.ThreadId = Thread.CurrentThread.ManagedThreadId;

                var gc = ClientPool.GetByThreadId(t.ThreadId);
                if (gc != null)
                    t.ClientId = gc.ClientAccountId;

                if (ex != null)
                {
                    t.ExceptionMessage = ex.Message;

                    if (ex.InnerException != null)
                        t.ExceptionInnerMessage = ex.InnerException.Message;
                }

                context.Traces.AddObject(t);
                context.SaveChanges();
            }
            catch (Exception e)
            {
                Console.WriteLine(String.Format("Oh dear, Database Logging Failed - {0}", e.Message));
                if (e.InnerException != null)
                    Console.WriteLine(e.InnerException.Message);

                string logDirectory = String.Format("{0}/ServerData/log.log", Environment.CurrentDirectory);

                FileStream fp = File.Open(logDirectory, FileMode.OpenOrCreate, FileAccess.ReadWrite);

                StreamWriter sw = new StreamWriter(fp);
                sw.Write(e.Message);

                sw.Close();
                fp.Close();
            }
        }

        private void ClearLog()
        {
            RPGXServerEntities context = new RPGXServerEntities();

            var traces = context.Traces;

            foreach (var t in traces)
            {
                context.Traces.DeleteObject(t);
            }

            context.SaveChanges();
        }

        #endregion
    }
}
